using System;
using System.Drawing;
using GeneticAlgorithms;
using GeneticAlgorithms.Genomes;
using WeifenLuo.WinFormsUI.Docking;
using ZedGraph;

namespace GADemo
{
    public partial class GraphForm : DockContent
    {
        private const int MaxGen = 1000;
        private const int GenWindow = 100;
        private const int WindowGap = 10;
        private const int WindowThreshold = GenWindow - WindowGap;

        public GraphForm()
        {
            InitializeComponent();
            
            pane = zedGraphControl1.GraphPane;
            zedGraphControl1.ScrollMinX = 0;
            zedGraphControl1.ScrollMaxX = MaxGen;

            zedGraphControl1.IsAutoScrollRange = true;
            zedGraphControl1.IsEnableHPan = true;
            zedGraphControl1.IsEnableHZoom = true;
            zedGraphControl1.ScrollGrace = ((float)WindowGap) / GenWindow;

            zedGraphControl1.IsShowHScrollBar = true;
            zedGraphControl1.IsSynchronizeXAxes = true;

            pane.Title.Text = "GA Evolution";
            pane.XAxis.Title.Text = "Generations";

            pane.XAxis.Scale.Min = 0;
            pane.XAxis.Scale.MinorStep = 1;
            pane.XAxis.Scale.Max = GenWindow;

            pane.YAxis.Title.Text = "Fitness";
            pane.YAxis.Scale.Min = 0;
            pane.YAxis.Scale.MinorStep = 10;
            pane.YAxis.Scale.Max = 110;

            zedGraphControl1.AxisChange();

            bestFitnessCurve = new LineItem("Best fitness");
            bestFitnessCurve.Line.Color = Color.Green;
            bestFitnessCurve.Symbol.Type = SymbolType.Triangle;

            avgFitnessCurve = new LineItem("Avg. fitness");
            avgFitnessCurve.Line.Color = Color.Blue;

            pane.CurveList.Add(bestFitnessCurve);
            pane.CurveList.Add(avgFitnessCurve);
        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }
        
        GraphPane pane;

        LineItem bestFitnessCurve;

        LineItem avgFitnessCurve;

        public void ResetGraph()
        {
            bestFitnessCurve.Clear();
            avgFitnessCurve.Clear();
            pane.XAxis.Scale.Min = 0;
            pane.XAxis.Scale.Max = GenWindow;
        }

        public void UpdateGraph(IGeneticAlgorithm ga)
        {
            IGenomeBase best = ga.GetBest();
            lblContents.Text = best.ToString();
            lblBestFitness.Text = best.Fitness.ToString();

            bestFitnessCurve.AddPoint(ga.Status.Generation, ga.Status.BestFitness);
            avgFitnessCurve.AddPoint(ga.Status.Generation, ga.Status.AverageFitness);

            if (ga.Status.Generation > WindowThreshold)
            {
                int rightBoundary = ga.Status.Generation + WindowGap;
                pane.XAxis.Scale.Max = rightBoundary;
                pane.XAxis.Scale.Min = rightBoundary - GenWindow;
            }
            
            zedGraphControl1.AxisChange();

            zedGraphControl1.Invalidate();
        }
    }
}

